﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AES小工具
{
    public partial class FrmAes : Form
    {
        public FrmAes()
        {
            InitializeComponent();
        }

        private void btnEncrypt_Click(object sender, EventArgs e)
        {
            if (tbEmpty.Checked == true && cbText2Hex.Checked == true)
            {
                bool flag = HexStringCheck(tbText.Text.Trim());
                if (flag == false)
                {
                    MessageBox.Show("十六进制数据不正确，请检查！");
                    return;
                }
            }
            
            if (cmbMode.SelectedIndex == 1) {
                if (cbText2Hex.Checked == true){
                    if (cmbPadding.SelectedIndex == 1)
                        EncryptCBCHex();
                    else
                        EncryptCBCHexPkcs7();
                } else {
                    if (cmbPadding.SelectedIndex == 1)
                        EncryptCBCAscii();
                    else
                        EncryptCBCAsciiPkcs7();
                }
            } else {
                if (cbText2Hex.Checked == true) {
                        EncryptECBHex();
                } else { 
                    EncryptECBAscii();
                }
            }
        }

        private void EncryptCBCHex() {
            string text = tbText.Text.Trim();

            byte[] bytes = HexString2Bytes(text);

            byte[] resultArr = AESHelper.AESEncrypt2CBC(bytes, tbKey.Text.Trim(), tbIv.Text.Trim());

            tbCryptograph.Text = Bytes2HexString(resultArr);
        }

        private void EncryptCBCHexPkcs7() {
            string text = tbText.Text.Trim();

            byte[] bytes = HexString2Bytes(text);

            byte[] resultArr = AESHelper.AESEncrypt2CBCPkcs7(bytes, tbKey.Text.Trim(), tbIv.Text.Trim());

            tbCryptograph.Text = Bytes2HexString(resultArr);
        }

        private void EncryptCBCAscii() {
            tbCryptograph.Text = AESHelper.AESEncrypt2CBC(tbText.Text, tbKey.Text.Trim(), tbIv.Text.Trim());
        }

        private void EncryptCBCAsciiPkcs7() {
            tbCryptograph.Text = AESHelper.AESEncrypt2CBCPkcs7(tbText.Text, tbKey.Text.Trim(), tbIv.Text.Trim());
        }

        private void EncryptECBHex() {
            string text = tbText.Text.Trim();

            byte[] bytes = HexString2Bytes(text);

            byte[] resultArr = AESHelper.AESEncrypt(bytes, tbKey.Text.Trim());

            tbCryptograph.Text = Bytes2HexString(resultArr);
        }

        private void EncryptECBAscii() {
            tbCryptograph.Text = AESHelper.AESEncrypt(tbText.Text, tbKey.Text.Trim());
        }

        private void btnDecode_Click(object sender, EventArgs e)
        {
            if(tbEmpty.Checked == true && cbText2Hex.Checked == true)
            {
                bool flag = HexStringCheck(tbCryptograph.Text.Trim());
                if (flag == false) {
                    MessageBox.Show("十六进制数据不正确，请检查！");
                    return;
                }
            }

            if (cmbMode.SelectedIndex == 1)
            {
                if (cbText2Hex.Checked == true) {
                    if(cmbPadding.SelectedIndex == 1)
                        DecodeCBCHex();
                    else
                        DecodeCBCHexPkcs7();
                } else {
                    if (cmbPadding.SelectedIndex == 1)
                        DecodeCBCAscii();
                    else
                        DecodeCBCAsciiPkcs7();
                }
            } else {
                if (cbText2Hex.Checked == true) {
                    DecodeECBHex();
                } else {
                    DecodeECBAscii();
                }
            }
        }

        private void DecodeCBCHex() {
            string text = tbCryptograph.Text.Trim();
            byte[] bytes = HexString2Bytes(text);
            byte[] resultArr = AESHelper.AESDecrypt2CBC(bytes, tbKey.Text.Trim(), tbIv.Text.Trim());
            if (cbCtyp2Hex.Checked)
                tbText.Text = Bytes2HexString(resultArr);
            if (cbCtyp2Ascii.Checked)
                tbText.Text = Bytes2AsciiString(resultArr);
            if (cbCtyp2Unicode.Checked)
                tbText.Text = Bytes2UnicodeString(resultArr);
        }

        private void DecodeCBCHexPkcs7() {
            string text = tbCryptograph.Text.Trim();
            byte[] bytes = HexString2Bytes(text);
            byte[] resultArr = AESHelper.AESDecrypt2CBCPkcs7(bytes, tbKey.Text.Trim(), tbIv.Text.Trim());
            if (cbCtyp2Hex.Checked)
                tbText.Text = Bytes2HexString(resultArr);
            if (cbCtyp2Ascii.Checked)
                tbText.Text = Bytes2AsciiString(resultArr);
            if (cbCtyp2Unicode.Checked)
                tbText.Text = Bytes2UnicodeString(resultArr);
        }

        private void DecodeCBCAscii() {
            tbText.Text = AESHelper.AESDecrypt2CBC(tbCryptograph.Text, tbKey.Text.Trim(), tbIv.Text.Trim());
        }

        private void DecodeCBCAsciiPkcs7() {
            tbText.Text = AESHelper.AESDecrypt2CBCPkcs7(tbCryptograph.Text, tbKey.Text.Trim(), tbIv.Text.Trim());
        }

        private void DecodeECBHex() {
            string text = tbCryptograph.Text.Trim();
            byte[] bytes = HexString2Bytes(text);
            byte[] resultArr = AESHelper.AESDecrypt(bytes, tbKey.Text.Trim());
            if (cbCtyp2Hex.Checked)
                tbText.Text = Bytes2HexString(resultArr);
            if (cbCtyp2Ascii.Checked)
                tbText.Text = Bytes2AsciiString(resultArr);
            if (cbCtyp2Unicode.Checked)
                tbText.Text = Bytes2UnicodeString(resultArr);
        }

        private void DecodeECBAscii() {
            tbText.Text = AESHelper.AESDecrypt(tbCryptograph.Text, tbKey.Text.Trim());
        }

        private byte[] HexString2Bytes(string text) {
            if (tbEmpty.Checked == true) {
                string[] textArr = text.Split(' ');
                byte[] bytes = new byte[textArr.Length];
                for (int index = 0; index < bytes.Length; index++){
                    bytes[index] = Convert.ToByte(textArr[index], 16);
                }
                return bytes;
            } else {
                text = text.ToUpper();//转为大写形式
                char[] chArr = text.ToArray();
                byte[] textArr = new byte[chArr.Length];
                int len = 0;
                int index = 0;
                byte b = 0;
                while (index < chArr.Length) {
                    b = 0;
                    if (chArr[index] == ' ') {
                        index++;
                        continue;
                    }
                    b = HexChar2Byte(chArr[index]);

                    index++;
                    if (chArr[index] == ' ') {
                        textArr[len++] = b;
                        index++;
                        continue;
                    }
                    b = (byte)(b << 4);
                    b += HexChar2Byte(chArr[index]);
                    textArr[len++] = b;
                    index++;
                }
                byte[] result = new byte[len];
                Array.Copy(textArr, result, len);
                return result;
            }
        }

        private byte HexChar2Byte(char ch) {
            int index = ch - '0';
            if (index >= 0 && index <= 9) {
                return (byte)index;
            } else if ((ch-'A') >=0 && (ch-'A')<=5) {
                return (byte)((ch - 'A') + 10);
            } else {
                return 0;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="resultArr"></param>
        /// <returns></returns>
        private string Bytes2HexString(byte[] resultArr) {
            string result = "";
            for (int index = 0; index < resultArr.Length; index++)
            {
                result += resultArr[index].ToString("X2");// + " ";
                if (tbEmpty.Checked == true) result += " ";
            }
            result = result.Trim();
            return result;
        }

        /// <summary>
        /// 转为ASCII字符编号
        /// </summary>
        /// <param name="resultArr"></param>
        /// <returns></returns>
        private string Bytes2AsciiString(byte[] resultArr)
        {
            return Encoding.ASCII.GetString(resultArr);
        }

        /// <summary>
        /// 转为unicode字符编码
        /// </summary>
        /// <param name="resultArr"></param>
        /// <returns></returns>
        private String Bytes2UnicodeString(byte[] resultArr)
        {
            return Encoding.Unicode.GetString(resultArr);   
        }

        /// <summary>
        /// 对十六进制字符进行检查
        /// </summary>
        /// <param name="hexStr"></param>
        /// <returns></returns>
        private bool HexStringCheck(string hexStr) {
            string[] strArr = hexStr.Split(' ');
            foreach (var str in strArr) {
                if (str.Length > 2) return false;
            }

            return true;
        }

        private void FrmAes_Load(object sender, EventArgs e)
        {
            cbCtyp2Ascii.Checked = true;
            cmbMode.SelectedIndex = 0;
            cmbLen.SelectedIndex = 0;
            cmbLen.Enabled = false;
            cmbPadding.SelectedIndex = 1;
            //cmbPadding.Enabled = false;
            cbText2Hex.Checked = true;

            

            try {
                string[] lines = File.ReadAllLines("C:\\En.bat");
                if (lines.Length == 3)
                {
                    cmbMode.SelectedIndex = Convert.ToInt32(lines[0]);
                    tbKey.Text = lines[1];
                    tbIv.Text = lines[2];
                }
            } catch { }
            
        }

        private void cmbMode_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (cmbMode.SelectedIndex)
            {
                /*case 0: {
                        tbIv.Text = "";
                        tbIv.Enabled = false;
                        tbIv2Hex.Enabled = false;
                    } break;*/
                case 1: {
                        cmbPadding.Enabled = true;
                        cmbPadding.SelectedIndex = 1;
                        tbIv.Enabled = true;
                        tbIv2Hex.Enabled = true;
                    } break;
                case 0:
                default: {
                        cmbPadding.Enabled=false;
                        cmbPadding.SelectedIndex = 1;
                        tbIv.Text = "";
                        tbIv.Enabled = false;
                        tbIv2Hex.Enabled = false;
                    } break;
            }
        }

        /*private void cbText2Hex_CheckedChanged(object sender, EventArgs e)
        {
            if (cbText2Hex.Checked == false) return;
            cbText2Ascii.Checked = !cbText2Hex.Checked;
        }

        private void cbText2Ascii_CheckedChanged(object sender, EventArgs e)
        {
            if (cbText2Ascii.Checked == false) return;
            cbText2Hex.Checked = !cbText2Ascii.Checked;
        }*/

        private void cbText2Hex_CheckedChanged(object sender, EventArgs e)
        {
            if (cbText2Hex.Checked == false) return;
            cbText2Ascii.Checked = !cbText2Hex.Checked;
            if(cbCtyp2Ascii.Checked) return;
            tbEmpty.Checked = cbText2Hex.Checked;
            tbEmpty.Enabled = cbText2Hex.Checked;
        }

        private void cbText2Ascii_CheckedChanged(object sender, EventArgs e)
        {
            if (cbText2Ascii.Checked == false) return;
            cbText2Hex.Checked = !cbText2Ascii.Checked;
            tbEmpty.Checked = !cbText2Ascii.Checked;
            tbEmpty.Enabled = cbText2Hex.Checked;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            string[] lines = { cmbMode.SelectedIndex.ToString(),tbKey.Text.Trim(),tbIv.Text.Trim()};
            File.WriteAllLines("C:\\En.bat", lines);
        }

        private void cmbPadding_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbPadding.SelectedIndex > 0) return;
            cmbPadding.SelectedIndex = 1;
        }

        private void cbCtyp2Hex_CheckedChanged(object sender, EventArgs e)
        {
            if (cbCtyp2Hex.Checked == false) { 
                return; 
            }

            cbCtyp2Ascii.Checked = false;
            cbCtyp2Unicode.Checked = false;
        }

        private void cbCtyp2Ascii_CheckedChanged(object sender, EventArgs e)
        {
            if (!cbCtyp2Ascii.Checked) { 
                return; 
            }
            cbCtyp2Hex.Checked = false;
            cbCtyp2Unicode.Checked = false;
        }

        private void cbCtyp2Unicode_CheckedChanged(object sender, EventArgs e)
        {
            if (!cbCtyp2Unicode.Checked) { 
                return; 
            }
            cbCtyp2Hex.Checked = false; 
            cbCtyp2Ascii.Checked = false;
        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }
    }
}
